package com.objecteffects.ilmp.tumblr.method;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;

import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;

/**
 * @author Rusty Wright
 */
@JsonInclude(JsonInclude.Include.ALWAYS)
public class Following {
    private final Meta meta;
    private final FollowingResponse followingResponse;

    // @JsonIgnore
    private final Map<String, Object> additionalProperties = new HashMap<>();

    @JsonCreator
    public Following(@JsonProperty("meta")
    final Meta _meta, @JsonProperty("response")
    final FollowingResponse _followingResponse) {
        this.meta = Objects.requireNonNull(_meta);
        this.followingResponse = Objects.requireNonNull(_followingResponse);
    }

    @JsonProperty("meta")
    public Meta getMeta() {
        return this.meta;
    }

    @JsonProperty("response")
    public FollowingResponse getResponse() {
        return this.followingResponse;
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(final String name, final Object value) {
        this.additionalProperties.put(name, value);
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    @Override
    public int hashCode() {
        return HashCodeBuilder.reflectionHashCode(this);
    }

    @Override
    public boolean equals(final Object other) {
        return EqualsBuilder.reflectionEquals(this, other);
    }

    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class FollowingResponse {
        private final int totalBlogs;
        private final List<Blog> blogs;

        // @JsonIgnore
        private final Map<String, Object> additionalProperties =
            new HashMap<>();

        @JsonCreator
        public FollowingResponse(@JsonProperty("total_blogs")
        final int _totalBlogs, @JsonProperty("blogs")
        final Blog[] _blogs) {
            this.totalBlogs = _totalBlogs;
            this.blogs = Arrays.asList(_blogs);
        }

        @JsonProperty("total_blogs")
        public int getTotalBlogs() {
            return this.totalBlogs;
        }

        @JsonProperty("blogs")
        public List<Blog> getBlogs() {
            return this.blogs;
        }

        @JsonAnyGetter
        public Map<String, Object> getAdditionalProperties() {
            return this.additionalProperties;
        }

        @JsonAnySetter
        public void
        setAdditionalProperty(final String name, final Object value) {
            this.additionalProperties.put(name, value);
        }

        @Override
        public String toString() {
            return ToStringBuilder.reflectionToString(this);
        }

        @Override
        public int hashCode() {
            return HashCodeBuilder.reflectionHashCode(this);
        }

        @Override
        public boolean equals(final Object other) {
            return EqualsBuilder.reflectionEquals(this, other);
        }
    }

    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class Blog {
        private final String name;
        private final String url;
        private final int updated;
        private final String title;
        private final String description;

        // @JsonIgnore
        private final Map<String, Object> additionalProperties =
            new HashMap<>();

        @JsonCreator
        public Blog(@JsonProperty("title")
        final String _title, @JsonProperty("name")
        final String _name, @JsonProperty("url")
        final String _url, @JsonProperty("updated")
        final int _updated, @JsonProperty("description")
        final String _description) {
            super();
            this.title = StringUtils.defaultIfBlank(_title, "");
            this.name = StringUtils.defaultIfBlank(_name, "");
            this.url = StringUtils.defaultIfBlank(_url, "");
            this.updated = _updated;
            this.description =
                StringEscapeUtils.escapeHtml4(StringUtils
                                              .defaultIfBlank(_description, ""));
        }

        @JsonProperty("title")
        public String getTitle() {
            return this.title;
        }

        @JsonProperty("name")
        public String getName() {
            return this.name;
        }

        @JsonProperty("url")
        public String getUrl() {
            return this.url;
        }

        @JsonProperty("updated")
        public int getUpdated() {
            return this.updated;
        }

        @JsonProperty("description")
        public String getDescription() {
            return this.description;
        }

        @JsonAnyGetter
        public Map<String, Object> getAdditionalProperties() {
            return this.additionalProperties;
        }

        @JsonAnySetter
        public void
            setAdditionalProperty(final String _name, final Object value) {
            this.additionalProperties.put(_name, value);
        }

        @Override
        public String toString() {
            return ToStringBuilder.reflectionToString(this);
        }

        @Override
        public int hashCode() {
            return HashCodeBuilder.reflectionHashCode(this);
        }

        @Override
        public boolean equals(final Object other) {
            return EqualsBuilder.reflectionEquals(this, other);
        }
    }
}
